
import csv
import casbin
from mysql_op import *
'''
思路：
1.后端实现操作
2.前端连接操作，并优化界面
3.数据库作为后台动态更新的策略存储，可用于机器的随时监控。使用casbin的csv检测不能实时监测
'''
'''
优化：可以引入其他线程加速、设置双线程守护、前端页面优化
'''

'''主逻辑不能下写，不能上读，写,同等级所有权限'''
info_list=[{'sub': 'root1', 'obj': 'core_file1', 'sub_level': '3', 'obj_level': '2','policy':'r-x'},
            {'sub': 'root2', 'obj': 'core_file2', 'sub_level': '3', 'obj_level': '3','policy':'rwx'},
            {'sub': 'root3', 'obj': 'core_file3', 'sub_level': '3', 'obj_level': '4','policy':'--x'}]
'''主逻辑不能下执行，不能上读，同等级无权限'''
info_list2=[{'sub': 'root1', 'obj': 'core_file1', 'sub_level': '3', 'obj_level': '2','policy':'rw-'},
            {'sub': 'root2', 'obj': 'core_file2', 'sub_level': '3', 'obj_level': '3','policy':'---'},
            {'sub': 'root3', 'obj': 'core_file3', 'sub_level': '3', 'obj_level': '4','policy':'-wx'}]

obj_file=[]
obj_file1_2=[]

obj_file2=[{'obj':'core_file1','Content':'Root1 have'},
           {'obj':'core_file2','Content':'Root2 have'},
           {'obj':'core_file3','Content':'Root3 have'}]
obj_file2_2=[{'obj':'core_file1','Content':'Root1 have'},
           {'obj':'core_file2','Content':'Root2 have'},
           {'obj':'core_file3','Content':'Root3 have'}]

Content_read=""
Content_read2=""
def check(e,sub,obj,act):
    ok = e.enforce(sub,obj,act)
    return ok

def get_policy(sub_level,obj_level):#####根据输入判断用户拥有的权限
    '''
   说明一下安全等级设置规则：
   当主体权限大于客体权限时，拥有权限r-x
   当主体权限小于客体权限时，拥有权限--x
   当主体权限等于客体权限时，拥有权限rwx
    '''
    #####
    if sub_level>obj_level:  ###表明主体的安全等级更高
        return "r-x"
    elif sub_level < obj_level:
        return "--x"
    else:
        return "rwx"
def get_policy2(sub_level,obj_level):#####根据输入判断用户拥有的权限
    '''
   说明一下安全等级设置规则：
   当主体权限大于客体权限时，拥有权限rw-
   当主体权限小于客体权限时，拥有权限-wx
   当主体权限等于客体权限时，拥有权限---
    '''
    #####
    if sub_level>obj_level:  ###表明主体的安全等级更高
        return "rw-"
    elif sub_level < obj_level:
        return "-wx"
    else:
        return "---"
def change_sub_level(sub,sub_level):####改变主体安全许可
    for i in info_list:
        try:
            if sub == 'root1' or sub == 'root2' or sub == 'root3' or int(sub_level)>4:
                return 1
            if sub == i['sub']:##修改的是对应主体的权限
                i['sub_level'] = sub_level
                s = get_policy(int(i['sub_level']),int(i['obj_level']))
                i['policy'] = s
                print("chang_sub_level success!")
                break
        except:
            print("change_sub_level error!")
    return 0
def change_sub_level2(sub,sub_level):
    for i in info_list:
        try:
            if sub == 'root1' or sub == 'root2' or sub == 'root3' or int(sub_level)>4:
                return 1
            if sub == i['sub']:##修改的是对应主体的权限
                i['sub_level'] = sub_level
                s = get_policy2(int(i['sub_level']),int(i['obj_level']))
                i['policy'] = s
                print("chang_sub_level success!")
                break
        except:
            print("change_sub_level error!")
    return 0 
def change_obj_level(obj,obj_level):####改变客体安全等级
    for i in info_list:
        try:
            if obj == 'core_file1' or obj == 'core_file2' or obj == 'core_file3' or int(obj_level)>4:
                return 1
            if obj == i['obj']:####说明是修改客体的权限
                i['obj_level'] = obj_level
                s = get_policy(int(i['sub_level']),int(i['obj_level']))
                i['policy'] = s
                print("chang_obj_level success!")
                break
        except:
            print("change_obj_level fail!")
    return 0
def change_obj_level2(obj,obj_level):
    for i in info_list:
        try:
            if obj == 'core_file1' or obj == 'core_file2' or obj == 'core_file3' or int(obj_level)>4:
                return 1
            if obj == i['obj']:####说明是修改客体的权限
                i['obj_level'] = obj_level
                s = get_policy2(int(i['sub_level']),int(i['obj_level']))
                i['policy'] = s
                print("chang_obj_level success!")
                break
        except:
            print("change_obj_level fail!")
    return 0
def make_change_table():####更新规则权限数据库存入变量
    data=[]
    try:
        for g in info_list:
            #print((g['sub'],g['obj'],g['sub_level'],g['obj_level'],g['policy']))
            data.append((g['sub'],g['obj'],g['sub_level'],g['obj_level'],g['policy']))
            print("data:",data)
        return data
    except:
        print("Data updates error!")
def make_change_table1_2():
    data=[]
    try:
        for g in info_list2:
            #print((g['sub'],g['obj'],g['sub_level'],g['obj_level'],g['policy']))
            data.append((g['sub'],g['obj'],g['sub_level'],g['obj_level'],g['policy']))
            print("data:",data)
        return data
    except:
        print("Data updates error!")
def make_change_table2():####更新文件对应内容数据库存入变量
    obj_f_l = []
    try:
        for ob in obj_file2:
            obj_f_l.append((ob['obj'],ob['Content']))
            print("obj_file",obj_f_l)
        return obj_f_l
    except:
        print("Obj_File update error!")
def make_change_table2_2():
    obj_f_l = []
    try:
        for ob in obj_file2_2:
            obj_f_l.append((ob['obj'],ob['Content']))
            print("obj_file",obj_f_l)
        return obj_f_l
    except:
        print("Obj_File update error!")
def input_info(sub_read,obj_read,sub_level,obj_level):####从前端获取输入信息
        sub_dict = {}
        if int(sub_level)>4 or int(obj_level)>4:
            return 0
        sub_dict['sub']=sub_read
        sub_dict['obj']=obj_read
        if obj_read not in obj_file:
            obj_file.append(obj_read)
            obj_file2.append({'obj':obj_read,'Content':"None"})
        
        sub_dict['sub_level']=sub_level
        sub_dict['obj_level']= obj_level
        sub_dict['policy'] = get_policy(int(sub_level),int(obj_level))
        print(sub_dict)
        info_list.append(sub_dict)
        '''到这里就完成了信息采集'''
        return 1
def input_info2(sub_read,obj_read,sub_level,obj_level):####从前端获取输入信息
        sub_dict = {}
        if int(sub_level)>4 or int(obj_level)>4:
            return 0
        sub_dict['sub']=sub_read
        sub_dict['obj']=obj_read
        if obj_read not in obj_file1_2:
            obj_file1_2.append(obj_read)
            obj_file2_2.append({'obj':obj_read,'Content':"None"})
        sub_dict['sub_level']=sub_level
        sub_dict['obj_level']= obj_level
        sub_dict['policy'] = get_policy2(int(sub_level),int(obj_level))
        print(sub_dict)
        info_list2.append(sub_dict)
        '''到这里就完成了信息采集'''
        return 1
def change_obj_info_file(sub,obj,option_write,content):####判断修改文件表，如果可以写就修改返回true  否则返回False
    Write_flag=0
    if option_write == "write":
        try:
            for f in info_list:
                if (sub=='root1' and obj=='core_file1') or (sub=='root2' and obj=='core_file2') or (sub=='root3' and obj=='core_file3'):
                    Write_flag = 0
                    return Write_flag
                if f['sub'] == sub and f['obj']==obj and (f['policy']=='rwx'):
                    Write_flag=1  ###表示可以写
                    for ob in obj_file2:
                        if obj == ob['obj'] and content != ob['Content']:
                            try:
                                ob['Content'] = content
                                print(ob['Content'])
                            except:
                                print("change_obj_info_file fail!")
                            break
                    return Write_flag
                else:
                    continue
        except:
            print("error!")
    else:
        print("OP error!")
    return Write_flag
def change_obj_info_file2(sub,obj,option_write,content):####判断修改文件表，如果可以写就修改返回true  否则返回False
    Write_flag=0
    if option_write == "write":
        try:
            for f in info_list2:
                if (sub=='root1' and obj=='core_file1') or (sub=='root2' and obj=='core_file2') or (sub=='root3' and obj=='core_file3'):
                    Write_flag = 0
                    return Write_flag
                if f['sub'] == sub and f['obj']==obj and (f['policy']=='rw-' or f['policy']=='-wx'):
                    Write_flag=1  ###表示可以写
                    for ob in obj_file2_2:
                        if obj == ob['obj'] and content != ob['Content']:
                            try:
                                ob['Content'] = content
                                print(ob['Content'])
                            except:
                                print("change_obj_info_file fail!")
                            break
                    return Write_flag
                else:
                    continue
        except:
            print("error!")
    else:
        print("OP error!")
    return Write_flag
def read_obj_info_file(sub,obj,option_read):####读取文件表（根据权限）
    global Content_read
    Read_flag=0  
    if option_read =="read":
        try:
            for f in info_list:
                if f['sub'] == sub and f['obj'] == obj and (f['policy'] == 'rwx' or f['policy'] == 'r-x'):
                    Read_flag=1
                    try:
                        for read in obj_file2:
                            if read['obj']==obj:
                                Content_read = read['Content']
                    except:
                        print("Read fail!")   
                    break
                else:
                    continue
            return (Read_flag,Content_read)
        except:
            print("read error!")
    return (Read_flag,"error")
def read_obj_info_file2(sub,obj,option_read):####读取文件表（根据权限）
    global Content_read2
    Read_flag=0  
    if option_read =="read":
        try:
            for f in info_list2:
                if f['sub'] == sub and f['obj'] == obj and (f['policy'] == 'rw-'):
                    Read_flag=1
                    try:
                        for read in obj_file2_2:
                            if read['obj']==obj:
                                Content_read2 = read['Content']
                    except:
                        print("Read fail!")   
                    break
                else:
                    continue
            return (Read_flag,Content_read2)
        except:
            print("read error!")
    return (Read_flag,"error")

def write_policy_csv():###尝试使用casbin，但是出了点问题，不想用了
    global Is_op
    try:
        # 1. 创建文件对象（指定文件名，模式，编码方式）
        with open("MAC.csv", "w", encoding="gbk", newline="") as f:
        # 2. 基于文件对象构建 csv写入对象
            csv_writer = csv.writer(f)
        # 3. 构建列表头
            #csv_writer.writerow(["sub", "obj", "act"])
        # 4. 写入csv文件内容
            for cs in info_list:
                csv_writer.writerow([cs['sub'], cs['obj'], cs['policy']])
            print("写入数据成功")
        # 5. 关闭文件
            f.close()
    except:
        print("写入数据失败")
    e = casbin.Enforcer("Mac.conf", "Mac.csv") 
    for i in info_list:
       print(e.enforce(i['sub'],i['obj'],i['policy']))